package com.fdb.efp.nls.service.impl.psd.credit;

import com.fdb.efp.nls.service.facade.NlsApplyRelationService;
import com.fdb.efp.nls.service.facade.NlsPublicService;
import com.fdb.efp.nls.service.facade.psd.PreNlsCreditInfoService;
import com.fdb.efp.nls.service.facade.sx.NlsCreditInfoService;
import com.fdb.efp.nls.service.vo.NlsApplyRelationVO;
import com.fdb.efp.nls.service.vo.psd.PreNlsCreditInfoVO;
import com.fdb.efp.nls.service.vo.queue.NlsProcessBizVO;
import com.fdb.efp.nls.service.vo.sx.NlsCreditInfoVO;
import com.gdrcu.efp.cus.common.CusBankRelEnum;
import com.gdrcu.efp.cus.common.CusStatusEnum;
import com.gdrcu.efp.cus.common.CusTypeEnum;
import com.fdb.basic.framework.core.base.FrameworkService;
import com.fdb.basic.framework.core.constant.SDicToExternalConstant;
import com.fdb.basic.framework.core.exception.BizException;
import com.fdb.basic.framework.core.util.DateUtility;
import com.fdb.basic.framework.core.util.SpringContextUtils;
import com.fdb.basic.framework.core.util.StringUtil;
import com.fdb.basic.framework.core.util.ValidationUtils;
import com.fdb.basic.framework.core.util.sdic.SDicToExternal;
import com.fdb.basic.sequence.service.facade.SequenceService;
import com.fdb.efp.nls.common.ConsoleConstant;
import com.fdb.efp.nls.service.vo.PrdInfoVO;
import com.fdb.efp.cus.service.facade.CusIndivRelService;
import com.fdb.efp.cus.service.facade.CusIndivService;
import com.fdb.efp.cus.service.vo.CusIndivRelVO;
import com.fdb.efp.cus.service.vo.CusIndivVO;
import com.fdb.efp.esb.common.constant.ESBClientConstance;
import com.fdb.efp.esb.service.bo.req.hj.ReqCusInfoCreBean;
import com.fdb.efp.esb.service.bo.resp.hj.RespCusInfoCreBean;
import com.fdb.efp.esb.service.facade.hj.CustomerInfoCreateService;
import com.fdb.efp.nls.service.impl.sx.CreditSoltServiceImpl;
import com.fdb.efp.rule.common.enumeration.RefuseType;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * 需求编号:2019D08--
 * 问题编号:
 * 开发人员: caoxin
 * 创建日期:2019/12/2
 * 功能描述:
 * 修改日期:2019/12/2
 * 修改描述:
 */
@Service("psdCusCreateService")
public class PsdCusCreateServiceImpl extends CreditSoltServiceImpl implements FrameworkService {
    @Override
    protected void doExecute(NlsProcessBizVO nlsProcessBizVo, NlsCreditInfoVO nlsCreditInfoVO) throws Exception {

        String applySeq = nlsCreditInfoVO.getLmtApplySeq();
        logger.info("======>普税贷客户建档服务开始,流水号" + applySeq + "<======");

        // 判断客户是否存在
        boolean exist = isCustomerExist(nlsCreditInfoVO);
        // 上送互金建档Bean
        RespCusInfoCreBean respCusInfoCreBean = new RespCusInfoCreBean();
        // 查询产品信息表
        PrdInfoVO prdInfoVo = nlsPublicService.getProInfo(nlsCreditInfoVO.getPrdId());
        // 客户
        CusIndivVO cusIndivVO = null;
        /*###################################################################################################*/
        /********************************* 客户建档插槽主流程 ************************************************/
        /*###################################################################################################*/
        try {
            // 根据预授信编号查询预授信表中的行业代码
            PreNlsCreditInfoVO inPreNlsCreditInfoVo = new PreNlsCreditInfoVO();
            inPreNlsCreditInfoVo.setApplySeq(nlsCreditInfoVO.getPreLmtApplySeq());
            PreNlsCreditInfoVO preNlsCreditInfoVO = preNlsCreditInfoService.queryByPk(inPreNlsCreditInfoVo);
            String industry = "";
            if (!Objects.isNull(preNlsCreditInfoVO) && !StringUtil.isNullorBank(preNlsCreditInfoVO.getIndustry())){
                industry = preNlsCreditInfoVO.getIndustry();
            }
            // 客户不存在
            if (!exist) {
                // 上送客户建档信息至互金
                respCusInfoCreBean = pushCusToOnlineFinance(nlsCreditInfoVO,industry);
                //插入客户表信息
                insertCustomerInfo(nlsCreditInfoVO, respCusInfoCreBean, prdInfoVo,preNlsCreditInfoVO);
            } else {
                // 更新客户表信息
                cusIndivVO = updateCustomerInfo(nlsCreditInfoVO, respCusInfoCreBean, prdInfoVo,preNlsCreditInfoVO);
            }
            // 更新授信申请客户id
            nlsCreditInfoVO.setCusId(Objects.isNull(respCusInfoCreBean.getUsrID()) ? cusIndivVO.getCusId() : respCusInfoCreBean.getUsrID());
            nlsProcessBizVo.setCusId(Objects.isNull(respCusInfoCreBean.getUsrID()) ? cusIndivVO.getCusId() : respCusInfoCreBean.getUsrID());
            // 发送短信
            BigDecimal amount = nlsCreditInfoVO.getApproveAmt().setScale(4, BigDecimal.ROUND_HALF_UP);
            DecimalFormat df = new DecimalFormat("###,###.00");
            String str = df.format(amount);
            nlsPublicService.sendSuccessMessage(nlsCreditInfoVO.getIndivMobile(),str);

        } catch (Exception e) {
            logger.error("======>【客户建档插槽】执行失败原因为<======", e.getMessage());
            nlsProcessBizVo.setExceptionFlag(Boolean.TRUE);
            nlsProcessBizVo.setRefuseMsg(RefuseType.OTHER.getMsg());
            nlsProcessBizVo.setExceptionMsg(e);
            nlsPublicService.sendFailMesage(nlsCreditInfoVO.getIndivMobile());
        } finally {
            logger.info("======>普税贷客户建档服务结束,流水号<======" + applySeq);
        }
    }

    /**
     * 设置客户基本信息: <br>
     * <p>
     * 0.1:caoxin:2019/4/24 16:50:  <br>
     *
     * @return
     * @author caoxin
     * @date 2019/4/24 16:50
     * @version 0.1
     * @since 2019/4/24 16:50
     */

    private CusIndivVO getCusIndivVO(NlsCreditInfoVO nlsCreditInfoVO, RespCusInfoCreBean respCusInfoCreBean, PrdInfoVO prdInfoVo) {
        CusIndivVO cusIndivVO = new CusIndivVO();
        // 核心客户号为空，证明是没有走客户调客户建档，存量数据；不更新
        if (StringUtils.isEmpty(respCusInfoCreBean.getClntNo())) {
            cusIndivVO.setCusId(getCusId(nlsCreditInfoVO));
        } else {
            // 客户号-存互金用户号
            cusIndivVO.setCusId(respCusInfoCreBean.getUsrID());
            // 内部客户ID-存互金客户号
            cusIndivVO.setInnerCusId(respCusInfoCreBean.getClntNo());
        }
        // 客户姓名
        cusIndivVO.setCusName(nlsCreditInfoVO.getCusName());
        // 客户性别
        cusIndivVO.setIndivSex(ValidationUtils.getSexFromIdNumber(nlsCreditInfoVO.getCertCode()).getEnname());
        // 客户证件类型
        cusIndivVO.setCertType(nlsCreditInfoVO.getCertType());
        // 客户证件号码
        cusIndivVO.setCertCode(nlsCreditInfoVO.getCertCode());
        // 证件到期日
        cusIndivVO.setIndivIdExpDt(nlsCreditInfoVO.getCertEndDt());
        // 证件地址
        cusIndivVO.setIndivRsdAddr(nlsCreditInfoVO.getIndivRsdAddr());
        // 客户手机号
        cusIndivVO.setPhone(nlsCreditInfoVO.getIndivMobile());
        // 客户类别
        cusIndivVO.setCusType(CusTypeEnum.NATURAL_MAN.getCode());
        // 关联银行
        cusIndivVO.setCusBankRel(CusBankRelEnum.NORMAL.getCode());
        // 客户状态
        cusIndivVO.setCusStatus(CusStatusEnum.OFFICIAL.getCode());
        // 首次申请渠道
        cusIndivVO.setFstAppChannel(nlsCreditInfoVO.getChannelNo());
        //生日
        cusIndivVO.setIndivDtOfBirth(ValidationUtils.getBirthdayFromIdNumber(nlsCreditInfoVO.getCertCode()));
        return cusIndivVO;
    }
    /****************************************************************************************************/
    /*********************************** 查询 ***********************************************************/
    /****************************************************************************************************/
    /**
     * 获取客户号: <br>
     * <p>
     * 0.1:caoxin:2019/4/24 17:14:  <br>
     *
     * @return
     * @author caoxin
     * @date 2019/4/24 17:14
     * @version 0.1
     * @since 2019/4/24 17:14
     */

    private String getCusId(NlsCreditInfoVO nlsCreditInfoVO) {
        // 授信申请信息不为空
        Objects.requireNonNull(nlsCreditInfoVO);
        // 通过身份证号码查询是否有该客户ID
        return cusIndivService.getCusIdByCertCode(nlsCreditInfoVO.getCertType(), nlsCreditInfoVO.getCertCode());
    }
    /****************************************************************************************************/
    /*********************************** 校验 ***********************************************************/
    /****************************************************************************************************/
    /**
     * 判断客户是否存在网贷系统: <br>
     * <p>
     * 0.1:caoxin:2019/4/22 21:15:  <br>
     *
     * @return
     * @author caoxin
     * @date 2019/4/22 21:15
     * @version 0.1
     * @since 2019/4/22 21:15
     */

    private boolean isCustomerExist(NlsCreditInfoVO nlsCreditInfoVO) {
        String cusId = getCusId(nlsCreditInfoVO);
        if (StringUtils.isNotEmpty(cusId)) {
            logger.info("网贷已存在该客户，客户号:" + cusId);
            return true;
        } else {
            logger.info("网贷不存在该客户，客户号");
            return false;
        }
    }
    /****************************************************************************************************/
    /*********************************** 落库 ***********************************************************/
    /****************************************************************************************************/

    /**
     * 插入客人信息: <br>
     * <p>
     * 0.1:caoxin:2019/4/22 21:31:  <br>
     *
     * @return
     * @author caoxin
     * @date 2019/4/22 21:31
     * @version 0.1
     * @since 2019/4/22 21:31
     */

    private void insertCustomerInfo(NlsCreditInfoVO nlsCreditInfoVO, RespCusInfoCreBean respCusInfoCreBean, PrdInfoVO prdInfoVo,PreNlsCreditInfoVO preNlsCreditInfoVO) throws BizException {
        CusIndivVO cusIndivVO = getCusIndivVO(nlsCreditInfoVO, respCusInfoCreBean, prdInfoVo);
        cusIndivVO.setComInitLoanDate(DateUtility.getCurrAppDateStr());
        cusIndivVO.setInputDate(DateUtility.getCurrAppDateStr());
        //企业类型
        cusIndivVO.setEntpType(preNlsCreditInfoVO.getBkColumn1());
        //行业码值
        cusIndivVO.setIndivComTyp(preNlsCreditInfoVO.getIndustry());
        setServerInsertDefaultProperty(cusIndivVO);
        int result = cusIndivService.insertCusIndiv(cusIndivVO);
        if (result != 1) {
            logger.error("=========>【客户建档插槽】,插入客户信息失败!!!<========", msgTemplate);
            throw new BizException("【客户建档插槽】,插入客户信息失败!!!", msgTemplate);
        }
    }

    /**
     * 上送客户建档信息到互金进行建档: <br>
     * 0.1:caoxin:2019/4/22 21:12:  <br>
     *
     * @return
     * @author caoxin
     * @date 2019/4/22 21:12
     * @version 0.1
     * @since 2019/4/22 21:12
     */

    private RespCusInfoCreBean pushCusToOnlineFinance(NlsCreditInfoVO nlsCreditInfoVO,String industry) throws BizException {
        ReqCusInfoCreBean reqCusInfoCreBean = new ReqCusInfoCreBean();
        // 手机号码
        reqCusInfoCreBean.setMblNo(nlsCreditInfoVO.getIndivMobile());
        // 客户姓名 Y
        reqCusInfoCreBean.setCustNm(nlsCreditInfoVO.getCusName());
        // 客户性别 男1 女2
        reqCusInfoCreBean.setUserGnd(ValidationUtils.getSexFromIdNumber(nlsCreditInfoVO.getCertCode()).getEnname());
        // 国籍
        reqCusInfoCreBean.setNation(StringUtil.replaceNullByObj(nlsCreditInfoVO.getNational()));
        // 职业
        reqCusInfoCreBean.setCrrCd(StringUtil.replaceNullByObj(nlsCreditInfoVO.getProfession()));
        // 详细地址
        reqCusInfoCreBean.setCtcAddr(StringUtil.replaceNullByObj(nlsCreditInfoVO.getCertAddr()));
        // 工作单位地址
        reqCusInfoCreBean.setWrkCorpAddr(nlsCreditInfoVO.getWrkCorpAddr());
        // 证件类型 Y
        reqCusInfoCreBean.setCertTp(nlsCreditInfoVO.getCertType());
        // 证件号码 Y
        reqCusInfoCreBean.setCertNo(nlsCreditInfoVO.getCertCode());
        // 证件有效期
        reqCusInfoCreBean.setIdenEfftDt(nlsCreditInfoVO.getCertEndDt().contains("长期") ? "20991231" : nlsCreditInfoVO.getCertEndDt().split("-")[1]);
        // 签发机关（默认中国）
        reqCusInfoCreBean.setIssueOrgNm(ConsoleConstant.CHINA);
        // 婚姻状况
        reqCusInfoCreBean.setMrgSitu(StringUtil.replaceNullByObj(nlsCreditInfoVO.getMrgSitu()));
        // 配偶姓名
        reqCusInfoCreBean.setSpsNm(StringUtil.replaceNullByObj(nlsCreditInfoVO.getSpsNm()));
        // 机构代码
        reqCusInfoCreBean.setInstId(ESBClientConstance.psdCreditInstId);
        // 全局流水号
        reqCusInfoCreBean.setGlobaNo(nlsCreditInfoVO.getGlobalSerno());
        // 渠道号
        reqCusInfoCreBean.setChannlNo(nlsCreditInfoVO.getChannelNo());
        // 行业代码
        reqCusInfoCreBean.setIndusCd(industry);
        try {
            // 产品类型 caoxin:这里还需要配置
            reqCusInfoCreBean.setProdType(SDicToExternal.getExternalSysDicVal(SDicToExternalConstant.SYSID_IFP, SDicToExternalConstant.PRD_TYPE, nlsCreditInfoVO.getPrdId()));
            // 推送信息到互金进行客户建档
            return customerInfoCreateService.customerInfoCreate(reqCusInfoCreBean);
        } catch (Exception e) {
            logger.error("=========>【客户建档插槽】调用互金核心客户建档异常<======" + e, msgTemplate);
            throw new BizException("【客户建档插槽】调用互金核心客户建档异常!!! " + e);
        }


    }

    /**
     * 插入客户关联人信息<br>
     * 0.1:caoxin:2019/6/25 20:40:  <br>
     *
     * @return
     * @author caoxin
     * @date 2019/6/25 20:40
     * @version 0.1
     * @since 2019/6/25 20:40
     */
    private void insertCustomerRelation(NlsCreditInfoVO nlsCreditInfoVO, NlsProcessBizVO nlsProcessBizVo, RespCusInfoCreBean respCusInfoCreBean) throws BizException {
        NlsApplyRelationVO nlsApplyRelationVo = new NlsApplyRelationVO();
        // 流水号
        nlsApplyRelationVo.setApplySeq(nlsProcessBizVo.getApplySeq());
        // 通过授信申请流水号查询，授信申请关联人【存在则更新】
        List<NlsApplyRelationVO> nlsApplyRelationVOs = Optional.ofNullable(nlsApplyRelationService.queryByApplySeq(nlsApplyRelationVo)).orElseGet(ArrayList::new);
        for (NlsApplyRelationVO vo : nlsApplyRelationVOs) {
            final CusIndivRelVO cusIndivRelVO = new CusIndivRelVO();
            String relSerno = "";
            try {
                relSerno = getCusId();
            } catch (Exception e) {
                throw new BizException("【客户建档插槽】,关联人流水号生成失败!!!");
            }
            cusIndivRelVO.setRelSerno(relSerno);
            cusIndivRelVO.setCusId(respCusInfoCreBean.getClntNo());
            cusIndivRelVO.setCertCode(vo.getCertCode());
            cusIndivRelVO.setCertType(vo.getCertType());
            cusIndivRelVO.setRelName(vo.getRelName());
            cusIndivRelVO.setRelation(vo.getRelRelation());
            cusIndivRelVO.setMobile(nlsCreditInfoVO.getIndivMobile());
            int result = cusIndivRelService.insertCusIndivRel(cusIndivRelVO);
            if (result != 1) {
                throw new BizException("【客户建档插槽】,关联人流水号生成失败!!!");
            }
        }
    }


    /**
     * 更新授信申请表表信息: <br>
     * <p>
     * 0.1:caoxin:2019/4/22 8:23:  <br>
     *
     * @return
     * @author caoxin
     * @date 2019/4/19 8:23
     * @version 0.1
     * @since 2019/4/19 8:23
     */

    private CusIndivVO updateCustomerInfo(NlsCreditInfoVO nlsCreditInfoVO, RespCusInfoCreBean respCusInfoCreBean, PrdInfoVO prdInfoVo,PreNlsCreditInfoVO preNlsCreditInfoVO) throws BizException {
        CusIndivVO cusIndivVO = getCusIndivVO(nlsCreditInfoVO, respCusInfoCreBean, prdInfoVo);
        cusIndivVO.setEntpType(preNlsCreditInfoVO.getBkColumn1());
        setServerUpdateDefaultProperty(cusIndivVO);
        int result = cusIndivService.updateByPk(cusIndivVO);
        if (result == -1) {
            logger.error("=========>【客户建档插槽】,更新客户信息失败!!!<======", msgTemplate);
            throw new BizException("【客户建档插槽】,更新客户信息失败!!!");
        }
        return cusIndivVO;

    }

    /**
     * 更新网贷申请客户号: <br>
     * <p>
     * 0.1:caoxin:2019/4/23 8:48: <br>
     *
     * @return
     * @author caoxin
     * @date 2019/4/23 8:48
     * @version 0.1
     * @since 2019/4/23 8:48
     */

    private void updateCreditApplyInfo(NlsCreditInfoVO nlsCreditInfoVO, RespCusInfoCreBean respCusInfoCreBean) throws BizException {
        // 获取核心客户号
        nlsCreditInfoVO.setCusId(respCusInfoCreBean.getClntNo());
        setServerUpdateDefaultProperty(nlsCreditInfoVO);
        int result = nlsCreditInfoService.updateByPk(nlsCreditInfoVO);
        if (result == -1) {
            logger.error("=========>【客户建档插槽】,插入客户信息失败!!!<======", msgTemplate);
            throw new BizException("【客户建档插槽】,插入客户信息失败!!!");
        }
    }

    /**
     * 生成客户ID: <br>
     * 0.1:caoxin:2019/6/24 19:21: <br>
     *
     * @return
     * @author caoxin
     * @date 2019/6/24 19:21
     * @version 0.1
     * @since 2019/6/24 19:21
     */
    public String getCusId() throws Exception {
        SequenceService sequenceService = (SequenceService) SpringContextUtils.getBean("dbSeqService");
        return sequenceService.getSequence("RELATION_ID", null, null);
    }

    /**
     * 日志信息
     */
    private final Logger logger = LoggerFactory.getLogger(PsdCusCreateServiceImpl.class);
    /**
     * 日志模板
     */
    private final String msgTemplate = "message{}";

    /**
     * 授信信息服务
     */
    @Autowired
    @Qualifier("nlsCreditInfoService")
    private NlsCreditInfoService nlsCreditInfoService;
    /**
     * 授信申请关联人服务
     */
    @Autowired
    @Qualifier("nlsApplyRelationService")
    private NlsApplyRelationService nlsApplyRelationService;
    /**
     * 产品信息服务
     */
    @Autowired
    @Qualifier("nlsPublicService")
    private NlsPublicService nlsPublicService;
    /**
     * 客人信息服务
     */
    @Autowired
    @Qualifier("cusIndivService")
    private CusIndivService cusIndivService;
    /**
     * 客人关联人服务
     */
    @Autowired
    @Qualifier("cusIndivRelService")
    private CusIndivRelService cusIndivRelService;
    /**
     * 客户建档接口
     */
    @Autowired
    @Qualifier("customerInfoCreateService")
    private CustomerInfoCreateService customerInfoCreateService;
    /**
     * 预授信信息服务
     */
    @Autowired
    @Qualifier("preNlsCreditInfoService")
    private PreNlsCreditInfoService preNlsCreditInfoService;

}
